package com.fred.xlog

import com.fred.util.Util
import com.fred.xlog.Log.LogImp
import java.io.File


class XLog : LogImp {

    companion object {
        const val LEVEL_ALL = 0
        const val LEVEL_VERBOSE = 0
        const val LEVEL_DEBUG = 1
        const val LEVEL_INFO = 2
        const val LEVEL_WARNING = 3
        const val LEVEL_ERROR = 4
        const val LEVEL_FATAL = 5
        const val LEVEL_NONE = 6
        const val COMPRESS_LEVEL1 = 1
        const val COMPRESS_LEVEL2 = 2
        const val COMPRESS_LEVEL3 = 3
        const val COMPRESS_LEVEL4 = 4
        const val COMPRESS_LEVEL5 = 5
        const val COMPRESS_LEVEL6 = 6
        const val COMPRESS_LEVEL7 = 7
        const val COMPRESS_LEVEL8 = 8
        const val COMPRESS_LEVEL9 = 9
        const val AppednerModeAsync = 0
        const val AppednerModeSync = 1
        const val ZLIB_MODE = 0
    }

    init {
        val rootPath = Util.resourcesPath
        val dlls = arrayListOf("${rootPath}zlib1.dll",
            "${rootPath}fLog.dll")
        dlls.forEach {filePath ->
            System.load(filePath)
        }
    }

    override fun logV(logInstancePtr: Long, tag: String?, fileName: String?, funcName: String?,
                      line: Int, pid: Int, tid: Long, mainTid: Long, log: String?) {
        logWrite2(logInstancePtr, LEVEL_VERBOSE, tag, fileName, funcName, line, pid, tid, mainTid, log)
    }

    override fun logD(logInstancePtr: Long, tag: String?, fileName: String?, funcName: String?,
                      line: Int, pid: Int, tid: Long, mainTid: Long, log: String?) {
        logWrite2(logInstancePtr, LEVEL_DEBUG, tag, fileName, funcName, line, pid, tid, mainTid, log)
    }

    override fun logI(logInstancePtr: Long, tag: String?, fileName: String?, funcName: String?,
                      line: Int, pid: Int, tid: Long, mainTid: Long, log: String?) {
        logWrite2(logInstancePtr, LEVEL_INFO, tag, fileName, funcName, line, pid, tid, mainTid, log)
    }

    override fun logW(logInstancePtr: Long, tag: String?, fileName: String?, funcName: String?,
                      line: Int, pid: Int, tid: Long, mainTid: Long, log: String?) {
        logWrite2(logInstancePtr, LEVEL_WARNING, tag, fileName, funcName, line, pid, tid, mainTid, log)
    }

    override fun logE(logInstancePtr: Long, tag: String?, fileName: String?, funcName: String?,
                      line: Int, pid: Int, tid: Long, mainTid: Long, log: String?) {
        logWrite2(logInstancePtr, LEVEL_ERROR, tag, fileName, funcName, line, pid, tid, mainTid, log)
    }

    override fun logF(logInstancePtr: Long, tag: String?, fileName: String?, funcName: String?,
                      line: Int, pid: Int, tid: Long, mainTid: Long, log: String?) {
        logWrite2(logInstancePtr, LEVEL_FATAL, tag, fileName, funcName, line, pid, tid, mainTid, log)
    }

    override fun appenderOpen(level: Int, mode: Int, cacheDir: String?, logDir: String?,
                              namePrefix: String?, cacheDays: Int) {
        val logConfig = XLogConfig()
        logConfig.level = level
        logConfig.mode = mode
        logConfig.logDir = logDir
        logConfig.namePrefix = namePrefix
        logConfig.compressMode = ZLIB_MODE
        logConfig.pubKey =
            "A06052F7499B91AB21161D50EA2E03D715B2F58B876C7D29DA384BCD22A3090110A2AE93A582DAE137C1C371C147BEADE30C46B4400F44429398ACC2B5F30544"
        //		logConfig.pubkey = "24fe7d543d61178496cbd0ea63d966e3018bfaf2fbd37333e3265a27ff367694526c6e0bba005df1fa893d7b0220f7ae4c98ee829083bb24a2f525b6579b3282";
        logConfig.cacheDir = cacheDir
        logConfig.cacheDays = cacheDays
        appenderOpen(logConfig)
    }

    external override fun getLogLevel(logInstancePtr: Long): Int
    external override fun setAppenderMode(logInstancePtr: Long, mode: Int)
    override fun openLogInstance(level: Int, mode: Int, cacheDir: String?, logDir: String?,
                                 namePrefix: String?, cacheDays: Int): Long {
        val logConfig = XLogConfig()
        logConfig.level = level
        logConfig.mode = mode
        logConfig.logDir = logDir
        logConfig.namePrefix = namePrefix
        logConfig.compressMode = ZLIB_MODE
        logConfig.pubKey = ""
        logConfig.cacheDir = cacheDir
        logConfig.cacheDays = cacheDays
        return newXlogInstance(logConfig)
    }

    external override fun getXlogInstance(namePrefix: String?): Long
    external override fun releaseXlogInstance(namePrefix: String?)
    private external fun newXlogInstance(logConfig: XLogConfig?): Long
    external override fun setConsoleLogOpen(logInstancePtr: Long, isOpen: Boolean) //set whether the console prints log
    external override fun appenderClose()
    external override fun appenderFlush(logInstancePtr: Long, isSync: Boolean)
    external override fun setMaxFileSize(logInstancePtr: Long, aliveSeconds: Long)
    external override fun setMaxAliveTime(logInstancePtr: Long, aliveSeconds: Long)
    private external fun appenderOpen(logConfig: XLogConfig)
    external fun logWrite(logInfo: XLoggerInfo?, log: String?)
    private external fun logWrite2(logInstancePtr: Long, level: Int, tag: String?, fileName: String?,
                                   funcName: String?, line: Int, pid: Int, tid: Long, mainTid: Long, log: String?)


}